<template>
  <div class="product-container">
    <div class="product-display">
      <!-- 缩略图区域 -->
      <div class="thumbnail-container">
        <div class="thumbnail-scroll" @wheel="handleThumbnailWheel">
          <div
            class="thumbnail-wrapper"
            :style="thumbnailWrapperStyle"
            role="list"
            aria-label="商品缩略图"
          >
            <div
              v-for="(thumbnail, index) in thumbnails"
              :key="thumbnail.id"
              class="thumbnail-item"
              :class="{ active: currentIndex === index }"
              @mouseenter="handleThumbnailHover(index)"
              @click="handleThumbnailClick(index)"
              @keydown.enter="handleThumbnailClick(index)"
              role="listitem"
              :aria-label="`查看${thumbnail.alt}`"
              :aria-current="currentIndex === index"
              tabindex="0"
            >
              <img
                :src="thumbnail.thumb"
                :alt="thumbnail.alt"
                loading="lazy"
                width="90"
                height="90"
              />
            </div>
          </div>
        </div>

        <div class="thumbnail-nav" v-if="showNavigation">
          <button
            class="nav-btn"
            :disabled="!canScrollUp"
            @click="scrollThumbnails(-1)"
            aria-label="向上滚动缩略图"
          >
            ↑
          </button>
          <button
            class="nav-btn"
            :disabled="!canScrollDown"
            @click="scrollThumbnails(1)"
            aria-label="向下滚动缩略图"
          >
            ↓
          </button>
        </div>
      </div>

      <!-- 主图区域 -->
      <div class="image-section">
        <div
          class="main-image-container"
          @mouseenter="handleMouseEnter"
          @mouseleave="handleMouseLeave"
          ref="mainImageContainerRef"
        >
          <img
            :src="currentImage.large"
            :alt="currentImage.alt"
            class="main-image"
            @mousemove="handleMagnifier"
            ref="mainImageRef"
            loading="eager"
            :width="imageInfo.displayedWidth"
            :height="imageInfo.displayedHeight"
          />
          <div
            class="magnifier"
            :style="magnifierStyle"
            aria-hidden="true"
          ></div>
        </div>

        <!-- 商品信息 -->
        <div class="product-info">
          <product-details />
        </div>

        <!-- 预览图区域 -->
        <div
          class="preview-container"
          :class="{ active: showPreview }"
          ref="previewContainerRef"
          aria-label="商品放大预览"
        >
          <img
            :src="currentImage.large"
            :alt="currentImage.alt"
            class="preview-image"
            :style="previewImageStyle"
            ref="previewImageRef"
            @load="handleImageLoad"
            loading="eager"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'

// 类型定义
interface Thumbnail {
  id: number
  thumb: string
  large: string
  alt: string
}

interface ImageInfo {
  naturalWidth: number
  naturalHeight: number
  displayedWidth: number
  displayedHeight: number
}

interface Transform {
  x: number
  y: number
}

interface PreviewImageStyle {
  transform: string
}

// 响应式数据
const thumbnails = ref<Thumbnail[]>([
  {
    id: 1,
    thumb:
      'https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品正面视图',
  },
  {
    id: 2,
    thumb:
      'https://images.unsplash.com/photo-1565849904461-04a58ad377e0?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1565849904461-04a58ad377e0?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品侧面视图',
  },
  {
    id: 3,
    thumb:
      'https://images.unsplash.com/photo-1583394838336-acd977736f90?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1583394838336-acd977736f90?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品背面视图',
  },
  {
    id: 4,
    thumb:
      'https://images.unsplash.com/photo-1592750475338-74b7b21085ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1592750475338-74b7b21085ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品细节展示',
  },
  {
    id: 5,
    thumb:
      'https://images.unsplash.com/photo-1598300042247-d088f8ab3a91?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1598300042247-d088f8ab3a91?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品屏幕显示',
  },
  {
    id: 6,
    thumb:
      'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品配件展示',
  },
  {
    id: 7,
    thumb:
      'https://images.unsplash.com/photo-1546054454-aa26e2b734c7?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1546054454-aa26e2b734c7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品使用场景',
  },
  {
    id: 8,
    thumb:
      'https://images.unsplash.com/photo-1585155770447-2f66e2a397b5?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
    large:
      'https://images.unsplash.com/photo-1585155770447-2f66e2a397b5?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80',
    alt: '商品包装展示',
  },
])

const currentIndex = ref(0)
const showPreview = ref(false)
const currentPosition = ref(0)

const previewImageStyle = ref<PreviewImageStyle>({
  transform: 'translate(0px, 0px)',
})

const magnifierStyle = ref({
  display: 'none',
  left: '0px',
  top: '0px',
})

// DOM 引用
const mainImageRef = ref<HTMLImageElement | null>(null)
const previewImageRef = ref<HTMLImageElement | null>(null)
const previewContainerRef = ref<HTMLDivElement | null>(null)
const mainImageContainerRef = ref<HTMLDivElement | null>(null)

// 性能优化相关
let animationFrameId: number | null = null
let animationId: number | null = null
let lastMoveTime = 0
const MOVE_THROTTLE = 16 // ~60fps

// 状态管理
const imageInfo = ref<ImageInfo>({
  naturalWidth: 0,
  naturalHeight: 0,
  displayedWidth: 0,
  displayedHeight: 0,
})

const currentTransform = ref<Transform>({ x: 0, y: 0 })
const targetTransform = ref<Transform>({ x: 0, y: 0 })

// 计算属性
const currentImage = computed(() => thumbnails.value[currentIndex.value])

const itemHeight = 105
const visibleItems = 4

const maxPosition = computed(() =>
  Math.max(0, thumbnails.value.length - visibleItems),
)
const canScrollUp = computed(() => currentPosition.value > 0)
const canScrollDown = computed(() => currentPosition.value < maxPosition.value)
const showNavigation = computed(() => thumbnails.value.length > visibleItems)

const thumbnailWrapperStyle = computed(() => ({
  transform: `translateY(-${currentPosition.value * itemHeight}px)`,
}))

// 重新添加鼠标悬停切换图片的方法
const handleThumbnailHover = (index: number) => {
  currentIndex.value = index
}

const handleThumbnailClick = (index: number) => {
  currentIndex.value = index
}

const handleThumbnailWheel = (event: WheelEvent) => {
  // 检测屏幕宽度，小于62rem时禁用滚动
  if (window.innerWidth < 62 * 16) {
    // 62rem转换为px
    return // 在移动端不处理滚轮事件
  }

  event.preventDefault()
  const delta = Math.sign(event.deltaY)
  scrollThumbnails(delta)
}

const scrollThumbnails = (direction: number) => {
  const newPosition = currentPosition.value + direction
  currentPosition.value = Math.max(0, Math.min(newPosition, maxPosition.value))
}

const handleImageLoad = () => {
  const previewImage = previewImageRef.value
  const mainImage = mainImageRef.value

  if (previewImage) {
    imageInfo.value = {
      ...imageInfo.value,
      naturalWidth: previewImage.naturalWidth,
      naturalHeight: previewImage.naturalHeight,
    }
  }

  if (mainImage) {
    const rect = mainImage.getBoundingClientRect()
    imageInfo.value = {
      ...imageInfo.value,
      displayedWidth: rect.width,
      displayedHeight: rect.height,
    }
  }
}

const handleMouseEnter = () => {
  showPreview.value = true
  // 重置位置
  currentTransform.value = { x: 0, y: 0 }
  targetTransform.value = { x: 0, y: 0 }

  // 确保图片尺寸信息是最新的
  setTimeout(() => {
    handleImageLoad()
  }, 50)
}

const smoothAnimation = () => {
  const DAMPING = 0.4
  const THRESHOLD = 1

  const diffX = targetTransform.value.x - currentTransform.value.x
  const diffY = targetTransform.value.y - currentTransform.value.y

  if (Math.abs(diffX) < THRESHOLD && Math.abs(diffY) < THRESHOLD) {
    currentTransform.value = { ...targetTransform.value }
    animationId = null
    return
  }

  currentTransform.value.x += diffX * DAMPING
  currentTransform.value.y += diffY * DAMPING

  // 更新 previewImageStyle 而不是直接操作 DOM
  previewImageStyle.value = {
    transform: `translate(-${currentTransform.value.x}px, -${currentTransform.value.y}px)`,
  }

  animationId = requestAnimationFrame(smoothAnimation)
}

const updateMagnifierPosition = (event: MouseEvent) => {
  const mainImage = mainImageRef.value
  const previewContainer = previewContainerRef.value

  if (!mainImage || !previewContainer || !showPreview.value) return

  const containerRect = mainImage.getBoundingClientRect()
  const x = event.clientX - containerRect.left
  const y = event.clientY - containerRect.top

  // 边界检查
  const boundedX = Math.max(0, Math.min(x, containerRect.width))
  const boundedY = Math.max(0, Math.min(y, containerRect.height))

  // 放大镜位置
  const magnifierSize = 180
  const halfMagnifier = magnifierSize / 2

  let magnifierX = boundedX - halfMagnifier
  let magnifierY = boundedY - halfMagnifier

  magnifierX = Math.max(
    0,
    Math.min(magnifierX, containerRect.width - magnifierSize),
  )
  magnifierY = Math.max(
    0,
    Math.min(magnifierY, containerRect.height - magnifierSize),
  )

  magnifierStyle.value = {
    display: 'block',
    left: `${magnifierX}px`,
    top: `${magnifierY}px`,
  }

  // 预览图位置计算
  const previewRect = previewContainer.getBoundingClientRect()
  const scaleX = imageInfo.value.naturalWidth / imageInfo.value.displayedWidth
  const scaleY = imageInfo.value.naturalHeight / imageInfo.value.displayedHeight

  const moveX = boundedX * scaleX - previewRect.width / 2
  const moveY = boundedY * scaleY - previewRect.height / 2

  const maxMoveX = Math.max(0, imageInfo.value.naturalWidth - previewRect.width)
  const maxMoveY = Math.max(
    0,
    imageInfo.value.naturalHeight - previewRect.height,
  )

  targetTransform.value = {
    x: Math.max(0, Math.min(moveX, maxMoveX)),
    y: Math.max(0, Math.min(moveY, maxMoveY)),
  }

  if (!animationId) {
    animationId = requestAnimationFrame(smoothAnimation)
  }
}

const handleMagnifier = (event: MouseEvent) => {
  const now = Date.now()
  if (now - lastMoveTime < MOVE_THROTTLE) return

  lastMoveTime = now

  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
  }

  animationFrameId = requestAnimationFrame(() => {
    updateMagnifierPosition(event)
    animationFrameId = null
  })
}

const handleMouseLeave = () => {
  showPreview.value = false
  magnifierStyle.value.display = 'none'
  cleanupAnimations()
}

const cleanupAnimations = () => {
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
    animationFrameId = null
  }
  if (animationId) {
    cancelAnimationFrame(animationId)
    animationId = null
  }
}

// 监听器
watch(currentIndex, () => {
  // 切换图片时重置状态
  currentTransform.value = { x: 0, y: 0 }
  targetTransform.value = { x: 0, y: 0 }
  previewImageStyle.value = {
    transform: 'translate(0px, 0px)',
  }
})

// 生命周期
onMounted(() => {
  // 使用 Intersection Observer 延迟加载尺寸信息
  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        setTimeout(handleImageLoad, 100)
        observer.disconnect()
      }
    })
  })

  if (mainImageRef.value) {
    observer.observe(mainImageRef.value)
  }
})

onUnmounted(() => {
  cleanupAnimations()
})
</script>

<style lang="scss" scoped>
.product-container {
  max-width: 75rem;
  width: 100%;
  //background: #ffffff;
  border-radius: 0.75rem;
  //box-shadow: 0 0.625rem 1.875rem rgba(0, 0, 0, 0.15);
  overflow: hidden;
  padding: 0.625rem 0.75rem;
  // 添加硬件加速
  transform: translateZ(0);
}

.product-display {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
}

.image-section {
  flex: 1;
  display: flex;
  gap: 0.625rem;
  min-width: 0;
  position: relative;
}

.thumbnail-container {
  width: 6.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  position: relative;
  flex-shrink: 0;
}

.thumbnail-scroll {
  height: 28.125rem;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
}

.thumbnail-wrapper {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  transition: transform 0.3s ease;
}

.thumbnail-item {
  width: 6.25rem;
  height: 6.25rem;
  border: 0.125rem solid #e8e8e8;
  border-radius: 0.5rem;
  cursor: pointer;
  overflow: hidden;
  transition: all 0.2s ease;
  position: relative;
  flex-shrink: 0;
  box-sizing: border-box;

  /* 去掉边框阴影，只保留边框 */
  box-shadow: none;

  &:hover {
    border-color: #ff6700;
    /* 悬停时也去掉阴影，只改变边框颜色 */
    box-shadow: none;
  }

  &.active {
    border-color: #ff6700;
    /* 激活状态也去掉阴影 */
    box-shadow: none;
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    // 优化图片渲染
    content-visibility: auto;
    contain: layout style paint;
  }
}

.thumbnail-nav {
  display: flex;
  justify-content: center;
  gap: 0.625rem;
  margin-top: 0.625rem;
}

.nav-btn {
  width: 1.875rem;
  height: 1.875rem;
  border-radius: 50%;
  background: #f0f0f0;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
  font-size: 1rem;
  color: #666;

  &:hover:not(:disabled) {
    background: #ff6700;
    color: white;
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

.main-image-container {
  width: 31.25rem;
  height: 31.25rem;
  border: 0.0625rem solid #e8e8e8;
  border-radius: 0.625rem;
  overflow: hidden;
  cursor: crosshair;
  box-shadow: 0 0.3125rem 0.9375rem rgba(0, 0, 0, 0.05);
  position: relative;
  flex-shrink: 0;
}

.main-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.magnifier {
  position: absolute;
  width: 11.25rem;
  height: 11.25rem;
  background-color: rgba(255, 255, 255, 0.6);
  border: 0.125rem solid #ff6700;
  border-radius: 50%;
  display: none;
  pointer-events: none;
  box-shadow: 0 0 1.25rem rgba(0, 0, 0, 0.2);
  z-index: 10;
  backdrop-filter: blur(1px);
  transform: translateZ(0);
  transition: all 0.05s ease-out;
}

.preview-container {
  width: 34.15rem;
  height: 31.25rem;
  //border: 0.0625rem solid #e8e8e8;
  border-radius: 0.625rem;
  overflow: hidden;
  position: absolute;
  right: 0;
  top: 0;
  //box-shadow: 0 0.3125rem 0.9375rem rgba(0, 0, 0, 0.05);
  display: none;
  flex-shrink: 0;
  transform: translateZ(0);
  opacity: 0;
  transition: opacity 0.15s ease;

  &.active {
    display: block;
    opacity: 1;
  }
}

.preview-image {
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  object-fit: none;
  position: absolute;
  top: 0;
  left: 0;
  // 优化重绘性能
  will-change: transform;
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  /* 大幅减少过渡时间，使用线性缓动让响应更即时 */
  transition: transform 0.08s linear;
  /* 硬件加速 */
  transform-style: preserve-3d;
}

.product-info {
  background: #ffffff;
  border-radius: 0.625rem;
  padding: 0.625rem;
}

.product-title {
  font-size: 1.625rem;
  font-weight: bold;
  margin-bottom: 0.9375rem;
  color: #222;
}

.product-price {
  color: #ff6700;
  font-size: 1.75rem;
  font-weight: bold;
  margin-bottom: 1.25rem;
}

.product-description {
  color: #666;
  line-height: 1.7;
  font-size: 1rem;
}

.product-features {
  margin-top: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
}

.feature-tag {
  background: #f0f7ff;
  color: #1890ff;
  padding: 0.375rem 0.75rem;
  border-radius: 1.25rem;
  font-size: 0.875rem;
}

@media (max-width: 62rem) {
  .product-display {
    flex-direction: column;
  }

  .image-section {
    flex-direction: column;
  }

  .thumbnail-container {
    width: 100%;
    //order: 3;
  }

  .thumbnail-scroll {
    height: 6.25rem;
    overflow-x: auto;
    flex-direction: row;
    /* 隐藏滚动条 */
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE and Edge */
  }

  .thumbnail-scroll::-webkit-scrollbar {
    display: none; /* Chrome, Safari and Opera */
  }

  .thumbnail-wrapper {
    flex-direction: row;
  }

  .preview-container {
    width: 100%;
    height: 25rem;
  }

  .main-image-container {
    width: 100%;
    height: 25rem;
  }

  .thumbnail-nav {
    display: none;
  }
}
</style>
